<!DOCTYPE html>

<meta charset="utf-8">
<title>Есть, что скрывать</title>
<section><figure><img src="cryptoparty-artwork/cryptoparty_global_logos_icons/global.svg"></figure></section>

<section><h1><i>Мне нечего скрывать</i></h1></section>
<section><p>Лукавите.
Говоря это, Вы говорите, что знаете будущее и что может пойти не так.
</p></section>
<section><p>
Времена <i>целевой</i> слежки закончились. <br>
Добро пожаловать <br> в мир <i>массовой</i> слежки.
</p></section>
<section><p>Массовая слежка <br> = <br> слежка за всеми</p></section>
<section><h1>Безопасность</h1></section>
<section><p>То, что находится между представлением того,
 как работают вещи и как они работают <i>на самом деле</i>.
</p></section>
<section><p>Безопасность - <br> не то, что можно купить, скачать или установить</p></section>
<section><h1>Безопасность - <br> это процесс</h1></section>

<section><h1><i>Интернет</i></h1></section>
<section><h1>Интернет вошел в нашу жизнь</h1></section>
<section><h1>Классно, но что это за штука такая?</h1></section>
<section><h1>Как передается информация через Интернет?</h1></section>
<section><h1>Интернет - <br> сеть сетей</h1></section>
<section><h1>Передача <br> из одной сети <br> в другую</h1></section>
<section><h1>Через множество посредников</h1></section>
<section><figure>
<img src="pet-media/internet/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/internet/2.png"/>
</figure></section>
<section><h1>Отлично! <br> У нас есть Интернет!</h1></section>
<section><h1>Подождите...</h1></section>
<section><h1>Кто все эти посредники?</h1></section>
<section><h1>Интернет - сеть, <br> построенная на доверии</h1></section>
<section><h1>Которого нет.</h1></section>
<section><figure>
<img src="pet-media/internet/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/internet/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/internet/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/internet/6.png"/>
</figure></section>
<section><h1>Посредниками <br> могут быть <br> <i>кто-угодно</i></h1></section>
<section><h1>Как же быть?</h1></section>


<section><h1>Нам нужна Криптография</h1></section>
<section><p>Криптография - <br> методы безопасных коммуникаций</p></section>
<section><h1>Что такое <br> шифрование?</h1></section>
<section><h1>Методы превращения полезной информации в шум</h1></section>
<section><h1>Шум, в котором никто не разбирается, кроме Вас</h1></section>
<section><p>было: cu at cryptoparty <br> стало: 9d23fb0afafa37a57dafa</p></section>
<section><h1><i>"Шифрование - <br> это сложно"</i></h1></section>
<section><h1>Компьютеры - это тоже сложно, но вы ими пользуетесь</h1></section>
<section><h1>пользоваться <br> ≠ <br> разбираться</h1></section>
<section><h1><i>"Шифрование - <br> для террористов <br> и военных"</i></h1></section>
<section><h1>Так же как и ножи - <br> для убийц и маньяков</h1></section>
<section><h1>Шифрование - инструмент. <br> Не более, не менее.</h1></section>


<section><h1><i>Какое бывает шифрование?</i></h1></section>
<section><h1><b>Симметричное</b></h1></section>
<section><h1>Единый ключ <br> на зашифровку <br> и на расшифровку</h1></section>
<section><h1><i>Почтовая аналогия</i></h1></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/6.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/symmetric/7.png"/>
</figure></section>
<section><p>Например, симметричный ключ <br> выглядит так: <br>
e3594d0ce14fd79425921123d8ec81ea
</p></section>
<section><h1>Да, но что, если Алиса не может встретится с Бобом <br> и передать ключ?</h1></section>

<!-- <section><h1>К тому же, надо иметь по ключу для каждого собеседника</h1></section> -->
<section><h1>Асимметричное</h1><br><h2>Криптосистема с публичным ключом</h2></section>
<section><h1><span style="color: #8eb000">Публичный ключ</span> <br> для зашифровки <br> <span style="color: #cf4500">Закрытый ключ</span> <br> для расшифровки</h1></section>
<section><h1><i>Почтовая аналогия</i></h1></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/6.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/7.png"/>
</figure></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/1.png"/>
</figure></section>
<section><p>Например, публичный ключ выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/gpg-public-key-example.png">
</figure></section>
<section><p>Например, закрытый ключ выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/gpg-private-key-example.png">
</figure></section>


<section><h1>Существует <br> обратная операция</h1><h2>"шифрование" закрытым ключом</h2></section>
<section><h1><i>Цифровая подпись</i></h1></section>
<section><p>Только Боб может создать подпись сообщения, которая связана только <br>с этим сообщением. <br> Её можно проверить с помощью публичного ключа Боба.</p></section>
<section><h1><i>Создание подписи</i></h1></section>
<section><figure>
<img src="pet-media/crypto/signature/signature-create-simplified.png">
</figure></section>
<section><h1><i>Проверка подписи</i></h1></section>
<section><figure>
<img src="pet-media/crypto/signature/signature-verify-simplified.png">
</figure></section>
<section><p>Например, подписанный документ выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/signature/gpg-signature-example.png">
</figure></section>

<section><h1>А что, если замок прислал <br> <i>не Боб</i>?</h1></section>
<section><h1>Надо убедиться, <br> что это его ключ</h1></section>

<section><h1><i>Ручная проверка <br> публичных ключей</i></h1></section>
<section><h1>Можно попросить кого-то подписать публичный ключ <h2>Если вы доверяете им</h2></h1></section>

<section><h1>Отпечаток ключа</h1><h2>Fingerprint</h2></section>
<section><p>Короткий "эквивалент" публичного ключа. <br>
Если отпечатки публичных ключей совпадают, значит совпадают и эти ключи.</p></section>
<section><p>Например, отпечаток ключа выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/gpg-fingerprint-example.png">
</figure></section>

<section><h1>Сквозное шифрование</h1></section>
<section><h1>Собеседники сами генерируют свои ключи</h1></section>
<section><h1>Содержимое доступно только им</h1></section>

<section><h1>Forward Secrecy <h2>Прямая секретность</h2></h1></section>

<section><p>При компрометации закрытого ключа предыдущие сообщения не поддаются расшифровке.</p></section>
<!--<section><p>Обоюдное создание одноразовых ключей, <br> которые не хранятся</p></section>-->
<section><h1>Хорошо, <br> мы используем шифрование</h1></section>
<section><h1>Содержание передаваемых нами данных неизвестно</h1></section>
<section><h1>Неужели этого недостаточно?</h1></section>


<section><h1>Метаданные</h1><h2> данные о данных</h2></section>
<section><p>Размер, время передачи, место отправки, получатель, источник...</p></section>
<section><p><i>"Метаданные мало, что дают,<br> собирайте, сколько хотите"</i></p></section>
<section><h1>Метаданные несут <br> огромную опасность</h1></section>
<section><p>"Мы убиваем людей <br> на основе метаданных" - <br> Майкл Хайден, директор АНБ (1999-2005)</p></section>
<section><h1>Наиболее интересны</h1></section>
<section><h1>Универсальны</h1></section>
<section><h1>Не зависят от языка</h1></section>
<section><h1>Малый объем</h1></section>
<section><h1>Из них можно <br> узнать больше, чем из самих данных</h1></section>
<section><p>Любимые места, заболевания, пристрастия, социальные связи, настроение, планы на будущее...</p></section>
<section><h1>Теперь с обязательным хранением</h1><h2>по закону - "до трех лет"</h2></section>

<section><h1><i>Важность <br>свободного ПО</i></h1></section>
<section><h1>Доступность <br> всех деталей <br> и исходного кода</h1></section>
<section><h1>Отсутствие ограничений на использование</h1></section>
<section><h1>Проверяемость</h1><h2>очень сложно встроить лазейки</h2></section>
<section><h1>Независимость</h1></section>
<section><h1><i>Основные инструменты <br> защиты приватности</i></h1></section>
<section><h1><i>Защита метаданных, сетевой активности и обход цензуры</i></h1></section>
<section><figure>
<img src="pet-media/tools/tor/logo/Tor-logo-2011-flat.png"/>
</figure></section>
<section><h1>The onion router </h1> <h2>Луковичный маршрутизатор</h1></section>
<section><h1>Луковичная маршрутизация</h1></section>
<section><h1>Маршрут выбирает пользователь, а не операторы сети</h1></section>
<section><h1>"Не существует вездесущего наблюдателя"</h1><h2>предположение</h2></section>
<section><h1>Никто не может контролировать <br><i>все</i> узлы</h1></section>
<section><figure>
<img src="pet-media/nsa/tor/king_red2.png"/>
</figure></section>
<section><h1>Как устроен Tor?</h1></section>
<section><h1>Без Tor</h1></section>

<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/6.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/internet/7.png"/>
</figure></section>

<section><h1>Выход в Интернет через Tor</h1></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/6.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/7.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/8.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/9.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/10.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/11.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/12.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/exit/13.png"/>
</figure></section>

<section><h1><i>Кто-то</i> говорит <i>с кое-кем</i></h1></section>
<section><h1><i>Выходной релей видит весь трафик!</i></h1></section>
<section><h1>Цель: <br><i>кто-то</i> говорит с <i>кем-то</i></h1></section>
<section><h1>Луковичные сервисы Tor <h2>Tor Onion Services</h2></h1></section>
<section><h1>Анонимность как клиента, <br> так и сервера</h1></section>
<section><h1>Публичные ключи <br> вместо имен <h2>Достаточно сгенерировать ключевую пару</h2></h1></section>
<section><h2>zkym3uprkoddlxpq.onion</h2></section>
<section><h2>facebookcorewwwi.onion</h2></section>
<section><h1>Сквозное шифрование</h1></section>
<section><h1>Forward Secrecy</h1></section>
<section><h1>Запускаются везде, <br> где есть tor</h1></section>

<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/6.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/7.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/8.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/9.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/10.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/tor/howitworks/png/rendezvous/11.png"/>
</figure></section>


<section><h1>Tor Browser</h1></section>
<section><h1>Mozilla Firefox* + tor  </h1><br><h2>* с огромным количеством исправлений <br> для повышения приватности</h2></section>
<section><p>Tor Browser <br> выглядит так:</p></section>
<section><figure>
<img src="pet-media/tools/tor/tor-browser-screenshot.png"/>
</figure></section>
<section><h1>Мосты</h1></section>
<section><p>Релеи Tor, <br> которых нет  в публичном <br> состоянии сети</p></section>
<section><p>Используются как <br> входные релеи <br> в цепочках</p></section>
<section><p>В чистом виде потеряли смысл. Для подключения к мостам используются...</p></section>
<section><h1>Подключаемые Транспорты</h1><h2>Pluggable Transports</h2></section>
<section><h1>Алгоритмы маскировки подключений Tor<h2>для обхода цензуры</h2></h1></section>



<section><h1><i>Защита чатов</i></h1></section>
<section><h1>OTR</h1><h2>Off-The-Record Messaging</h2></section>
<section><h1>Почему OTR?</h1></section>
<section><h1>Открытый</h1></section>
<section><h1>Хорошо проанализирован</h1></section>
<section><h1>Отрицание авторства</h1></section>
<section><h1>Forward Secrecy</h1></section>
<section><figure>
<img src="pet-media/nsa/no-decrypt/otr-no-decrypt.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how1.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how2.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how3.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how4.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how5.png"/>
</figure></section>
<section><figure>
<img src="pet-media/tools/otr/png/otr-how6.png"/>
</figure></section>
<section><p>Сообщение OTR выглядит так: <br>
?OTRv2?Y3J5cHRvcGFydHkK
</p></section>
<section><h1>В текущей версии протокола нет передачи файлов <h2>Используйте OnionShare или PGP</h2></h1></section>
<section><h1>Предпочтительный вариант <br> использования OTR</h1></section>
<section><h1>Протокол XMPP</h1></section>
<section><h1>Похож на эл. почту</h1></section>
<section><p>cryptoparty@jabber.ccc.de</p></section>
<section><h1>Децентрализованный</h1></section>
<section><h1>Можно зарегистрироваться <br> на любом сервере</h1></section>
<section><h1>Можно связываться с пользователями на любом сервере</h1></section>
<section><h1>Но не распределенный!</h1></section>


<section><h1><i>Защита файлов и почты</i></h1></section>
<section><h1>PGP</h1></section>
<section><h1>Pretty Good Privacy</h1></section>
<section><h1>Почему PGP?</h1></section>
<section><h1>30 лет шифрования <br> "военного уровня"</h1></section>
<section><h1>Многочисленные аудиты</h1></section>
<section><h1>Стандарт интернета</h1></section>
<section><figure>
<img src="pet-media/nsa/no-decrypt/pgp_no_decrypt.png"/>
</figure></section>
<section><h1>Как работает PGP?</h1></section>
<section><figure>
<img src="pet-media/tools/pgp/pgp_all.png"/>
</figure></section>
<section><p>Публичный ключ выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/encryption/asymmetric/gpg-public-key-example.png">
</figure></section>
<section><p>Например, зашифрованное сообщение выглядит так:
</p></section>
<section><figure>
<img src="pet-media/crypto/encryption/gpg-encryption-example.png">
</figure></section>
<section><h1>Сертификат отзыва</h1></section>
<section><p>Сообщение о недействительности <br>ключа, подписанное самим ключом.<br>
При публикации сертификата ключ "становится недействительным"</p></section>

<section><h1><i>Защита работы на компьютере</i></section>
<section><h1>Tails</h1></section>
<section><h1>Запускается с флешки</h1></section>
<section><h1>Ориентированный на приватность <br> вариант GNU\Linux</h1></section>
<section><h1>Все соединения через Tor/I2P</h1></section>
<section><h1>OTR, GPG и все,<br> что нужно для работы</h1></section>

<section><h1>Ссылки</h1></section>
<section><p>Tor <br> https://torproject.org/ <br> Orbot (Android) </p></section>
<section><p>OTR <br> Pidgin/Adium/CoyIM <br> (Linux, Windows, macOS) <br> Conversations (Android) <br> ChatSecure (iOS, Android) </p></section>
<section><p>GnuPG <br> https://gnupg.org/ <br> GnuPG+Thunderbird+Enigmail (Desktop) <br>OpenKeyChain+K9-Mail (Android) <br> </p></section>
<section><p>Tails <br> https://tails.boum.org/</p></section>




<!-- Your Style -->
<!-- Define the style of your presentation -->

<style>
	/*
  @font-face {
    font-family: 'P22 Underground CY Pro';
    font-weight: bold;
    src: local('P22 Underground CY Pro Demi'), url(P22UndergroundCYPro-Demi.woff) format('woff');
  }*/
  @font-face {
    font-family: 'P22 Underground CY Pro';
    src: local('P22 Underground CY Pro Book'), url(fonts/P22UndergroundCYPro-Book.woff) format('woff');
  }

  html, .view body { background-color: #314046; counter-reset: slideidx; }
  body, .view section { background-color: #314046 }
  /* A section is a slide. It's size is 800x600, and this will never change */
  section, .view head > title {
      font-family: 'P22 Underground CY Pro', serif;
      font-size: 30px;
      color: #DEE2EB;
  }

  .view section:after {
    counter-increment: slideidx;
    content: counter(slideidx, decimal-leading-zero);
    position: absolute; bottom: -80px; right: 100px;
    color: white;
  }

  .view head > title {
    color: white;
    text-align: center;
    margin: 1em 0 1em 0;
  }

  h1, h2, p {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
  }
  h1 {
    font-size: 70px;
  }
  h2 {
    font-size: 40px;
  }
  h3 {
    margin: 100px 0 50px 100px;
  }

  ul {
      margin: 50px 200px;
  }
  li > ul {
      margin: 15px 50px;
  }

  p {
    /*margin: 75px;*/
    font-size: 50px;
  }

  blockquote {
    height: 100%;
    background-color: black;
    color: white;
    font-size: 60px;
    padding: 50px;
  }
  blockquote:before {
    content: open-quote;
  }
  blockquote:after {
    content: close-quote;
  }

  /* Figures are displayed full-page, with the caption
     on top of the image/video */
  figure {
    /* background-color: black; */
    width: 100%;
    height: 100%;
  }
  figure > * {
    position: absolute;
  }
  figure > img, figure > video {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    max-width: 100%;
    max-height: 100%;
  }
  figcaption {
    margin: 70px;
    font-size: 50px;
  }

  footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 40px;
    text-align: right;
    background-color: #F3F4F8;
    border-top: 1px solid #CCC;
  }

  /* Transition effect */
  /* Feel free to change the transition effect for original
     animations. See here:
     https://developer.mozilla.org/en/CSS/CSS_transitions
     How to use CSS3 Transitions: */
/*  section {
    -moz-transition: left 300ms linear 0s;
    -webkit-transition: left 300ms linear 0s;
    -ms-transition: left 300ms linear 0s;
    transition: left 300ms linear 0s;
  }
*/
  .view section {
    -moz-transition: none;
    -webkit-transition: none;
    -ms-transition: none;
    transition: none;
  }

  .view section[aria-selected] {
    border: 5px red solid;
  }

  /* Before */
  section { left: -150%; }
  /* Now */
  section[aria-selected] { left: 0; }
  /* After */
  section[aria-selected] ~ section { left: +150%; }

  /* Incremental elements */

  /* By default, visible */
  .incremental > * { opacity: 1; }

  /* The current item */
  .incremental > *[aria-selected] { opacity: 1; }

  /* The items to-be-selected */
  .incremental > *[aria-selected] ~ * { opacity: 0; }

  /* The progressbar, at the bottom of the slides, show the global
     progress of the presentation. */
  #progress-bar {
    height: 3px;
    background: #AAA;
  }
</style>

<!-- {{{{ dzslides core
#
#
#     __  __  __       .  __   ___  __
#    |  \  / /__` |    | |  \ |__  /__`
#    |__/ /_ .__/ |___ | |__/ |___ .__/ core :€
#
#
# The following block of code is not supposed to be edited.
# But if you want to change the behavior of these slides,
# feel free to hack it!
#
-->

<div id="progress-bar"></div>

<!-- Default Style -->
<style>
  * { margin: 0; padding: 0; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
  [role="note"] { display: none; }
  body {
    width: 800px; height: 600px;
    margin-left: -400px; margin-top: -300px;
    position: absolute; top: 50%; left: 50%;
    overflow: hidden;
    display: none;
  }
  .view body {
    position: static;
    margin: 0; padding: 0;
    width: 100%; height: 100%;
    display: inline-block;
    overflow: visible; overflow-x: hidden;
    /* undo Dz.onresize */
    transform: none !important;
    -moz-transform: none !important;
    -webkit-transform: none !important;
    -o-transform: none !important;
    -ms-transform: none !important;
  }
  .view head, .view head > title { display: block }
  section {
    position: absolute;
    pointer-events: none;
    width: 100%; height: 100%;
  }
  .view section {
    pointer-events: auto;
    position: static;
    width: 800px; height: 600px;
    margin: -150px -200px;
    float: left;

    transform: scale(.4);
    -moz-transform: scale(.4);
    -webkit-transform: scale(.4);
    -o-transform: scale(.4);
    -ms-transform: scale(.4);
  }
  .view section > * { pointer-events: none; }
  section[aria-selected] { pointer-events: auto; }
  html { overflow: hidden; }
  html.view { overflow: visible; }
  body.loaded { display: block; }
  .incremental {visibility: hidden; }
  .incremental[active] {visibility: visible; }
  #progress-bar{
    bottom: 0;
    position: absolute;
    -moz-transition: width 400ms linear 0s;
    -webkit-transition: width 400ms linear 0s;
    -ms-transition: width 400ms linear 0s;
    transition: width 400ms linear 0s;
  }
  .view #progress-bar {
    display: none;
  }
</style>

<script>
  var Dz = {
    remoteWindows: [],
    idx: -1,
    step: 0,
    html: null,
    slides: null,
    progressBar : null,
    params: {
      autoplay: "1"
    }
  };

  Dz.init = function() {
    document.body.className = "loaded";
    this.slides = Array.prototype.slice.call($$("body > section"));
    this.progressBar = $("#progress-bar");
    this.html = document.body.parentNode;
    this.setupParams();
    this.onhashchange();
    this.setupTouchEvents();
    this.onresize();
    this.setupView();
  }

  Dz.setupParams = function() {
    var p = window.location.search.substr(1).split('&');
    p.forEach(function(e, i, a) {
      var keyVal = e.split('=');
      Dz.params[keyVal[0]] = decodeURIComponent(keyVal[1]);
    });
  // Specific params handling
    if (!+this.params.autoplay)
      $$.forEach($$("video"), function(v){ v.controls = true });
  }

  Dz.onkeydown = function(aEvent) {
    // Don't intercept keyboard shortcuts
    if (aEvent.altKey
      || aEvent.ctrlKey
      || aEvent.metaKey
      || aEvent.shiftKey) {
      return;
    }
    if ( aEvent.keyCode == 37 // left arrow
      || aEvent.keyCode == 38 // up arrow
      || aEvent.keyCode == 33 // page up
    ) {
      aEvent.preventDefault();
      this.back();
    }
    if ( aEvent.keyCode == 39 // right arrow
      || aEvent.keyCode == 40 // down arrow
      || aEvent.keyCode == 34 // page down
    ) {
      aEvent.preventDefault();
      this.forward();
    }
    if (aEvent.keyCode == 35) { // end
      aEvent.preventDefault();
      this.goEnd();
    }
    if (aEvent.keyCode == 36) { // home
      aEvent.preventDefault();
      this.goStart();
    }
    if (aEvent.keyCode == 32) { // space
      aEvent.preventDefault();
      this.toggleContent();
    }
    if (aEvent.keyCode == 70) { // f
      aEvent.preventDefault();
      this.goFullscreen();
    }
    if (aEvent.keyCode == 79) { // o
      aEvent.preventDefault();
      this.toggleView();
    }
  }

  /* Touch Events */

  Dz.setupTouchEvents = function() {
    var orgX, newX;
    var tracking = false;

    var db = document.body;
    db.addEventListener("touchstart", start.bind(this), false);
    db.addEventListener("touchmove", move.bind(this), false);

    function start(aEvent) {
      aEvent.preventDefault();
      tracking = true;
      orgX = aEvent.changedTouches[0].pageX;
    }

    function move(aEvent) {
      if (!tracking) return;
      newX = aEvent.changedTouches[0].pageX;
      if (orgX - newX > 100) {
        tracking = false;
        this.forward();
      } else {
        if (orgX - newX < -100) {
          tracking = false;
          this.back();
        }
      }
    }
  }

  Dz.setupView = function() {
    document.body.addEventListener("click", function ( e ) {
      if (!Dz.html.classList.contains("view")) return;
      if (!e.target || e.target.nodeName != "SECTION") return;

      Dz.html.classList.remove("view");
      Dz.setCursor(Dz.slides.indexOf(e.target) + 1);
    }, false);
  }

  /* Adapt the size of the slides to the window */

  Dz.onresize = function() {
    var db = document.body;
    var sx = db.clientWidth / window.innerWidth;
    var sy = db.clientHeight / window.innerHeight;
    var transform = "scale(" + (1/Math.max(sx, sy)) + ")";

    db.style.MozTransform = transform;
    db.style.WebkitTransform = transform;
    db.style.OTransform = transform;
    db.style.msTransform = transform;
    db.style.transform = transform;
  }


  Dz.getNotes = function(aIdx) {
    var s = $("section:nth-of-type(" + aIdx + ")");
    var d = s.$("[role='note']");
    return d ? d.innerHTML : "";
  }

  Dz.onmessage = function(aEvent) {
    var argv = aEvent.data.split(" "), argc = argv.length;
    argv.forEach(function(e, i, a) { a[i] = decodeURIComponent(e) });
    var win = aEvent.source;
    if (argv[0] === "REGISTER" && argc === 1) {
      this.remoteWindows.push(win);
      this.postMsg(win, "REGISTERED", document.title, this.slides.length);
      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
      return;
    }
    if (argv[0] === "BACK" && argc === 1)
      this.back();
    if (argv[0] === "FORWARD" && argc === 1)
      this.forward();
    if (argv[0] === "START" && argc === 1)
      this.goStart();
    if (argv[0] === "END" && argc === 1)
      this.goEnd();
    if (argv[0] === "TOGGLE_CONTENT" && argc === 1)
      this.toggleContent();
    if (argv[0] === "SET_CURSOR" && argc === 2)
      window.location.hash = "#" + argv[1];
    if (argv[0] === "GET_CURSOR" && argc === 1)
      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
    if (argv[0] === "GET_NOTES" && argc === 1)
      this.postMsg(win, "NOTES", this.getNotes(this.idx));
  }

  Dz.toggleContent = function() {
    // If a Video is present in this new slide, play it.
    // If a Video is present in the previous slide, stop it.
    var s = $("section[aria-selected]");
    if (s) {
      var video = s.$("video");
      if (video) {
        if (video.ended || video.paused) {
          video.play();
        } else {
          video.pause();
        }
      }
    }
  }

  Dz.setCursor = function(aIdx, aStep) {
    // If the user change the slide number in the URL bar, jump
    // to this slide.
    aStep = (aStep != 0 && typeof aStep !== "undefined") ? "." + aStep : ".0";
    window.location.hash = "#" + aIdx + aStep;
  }

  Dz.onhashchange = function() {
    var cursor = window.location.hash.split("#"),
        newidx = 1,
        newstep = 0;
    if (cursor.length == 2) {
      newidx = ~~cursor[1].split(".")[0];
      newstep = ~~cursor[1].split(".")[1];
      if (newstep > Dz.slides[newidx - 1].$$('.incremental > *').length) {
        newstep = 0;
        newidx++;
      }
    }
    this.setProgress(newidx, newstep);
    if (newidx != this.idx) {
      this.setSlide(newidx);
    }
    if (newstep != this.step) {
      this.setIncremental(newstep);
    }
    for (var i = 0; i < this.remoteWindows.length; i++) {
      this.postMsg(this.remoteWindows[i], "CURSOR", this.idx + "." + this.step);
    }
  }

  Dz.back = function() {
    if (this.idx == 1 && this.step == 0) {
      return;
    }
    if (this.step == 0) {
      this.setCursor(this.idx - 1,
                     this.slides[this.idx - 2].$$('.incremental > *').length);
    } else {
      this.setCursor(this.idx, this.step - 1);
    }
  }

  Dz.forward = function() {
    if (this.idx >= this.slides.length &&
        this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
        return;
    }
    if (this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
      this.setCursor(this.idx + 1, 0);
    } else {
      this.setCursor(this.idx, this.step + 1);
    }
  }

  Dz.goStart = function() {
    this.setCursor(1, 0);
  }

  Dz.goEnd = function() {
    var lastIdx = this.slides.length;
    var lastStep = this.slides[lastIdx - 1].$$('.incremental > *').length;
    this.setCursor(lastIdx, lastStep);
  }

  Dz.toggleView = function() {
    this.html.classList.toggle("view");

    if (this.html.classList.contains("view")) {
      $("section[aria-selected]").scrollIntoView(true);
    }
  }

  Dz.setSlide = function(aIdx) {
    this.idx = aIdx;
    var old = $("section[aria-selected]");
    var next = $("section:nth-of-type("+ this.idx +")");
    if (old) {
      old.removeAttribute("aria-selected");
      var video = old.$("video");
      if (video) {
        video.pause();
      }
    }
    if (next) {
      next.setAttribute("aria-selected", "true");
      if (this.html.classList.contains("view")) {
        next.scrollIntoView();
      }
      var video = next.$("video");
      if (video && !!+this.params.autoplay) {
        video.play();
      }
    } else {
      // That should not happen
      this.idx = -1;
      // console.warn("Slide doesn't exist.");
    }
  }

  Dz.setIncremental = function(aStep) {
    this.step = aStep;
    var old = this.slides[this.idx - 1].$('.incremental > *[aria-selected]');
    if (old) {
      old.removeAttribute('aria-selected');
    }
    var incrementals = $$('.incremental');
    if (this.step <= 0) {
      $$.forEach(incrementals, function(aNode) {
        aNode.removeAttribute('active');
      });
      return;
    }
    var next = this.slides[this.idx - 1].$$('.incremental > *')[this.step - 1];
    if (next) {
      next.setAttribute('aria-selected', true);
      next.parentNode.setAttribute('active', true);
      var found = false;
      $$.forEach(incrementals, function(aNode) {
        if (aNode != next.parentNode)
          if (found)
            aNode.removeAttribute('active');
          else
            aNode.setAttribute('active', true);
        else
          found = true;
      });
    } else {
      setCursor(this.idx, 0);
    }
    return next;
  }

  Dz.goFullscreen = function() {
    var html = $('html'),
        requestFullscreen = html.requestFullscreen || html.requestFullScreen || html.mozRequestFullScreen || html.webkitRequestFullScreen;
    if (requestFullscreen) {
      requestFullscreen.apply(html);
    }
  }
  
  Dz.setProgress = function(aIdx, aStep) {
    var slide = $("section:nth-of-type("+ aIdx +")");
    if (!slide)
      return;
    var steps = slide.$$('.incremental > *').length + 1,
        slideSize = 100 / (this.slides.length - 1),
        stepSize = slideSize / steps;
    this.progressBar.style.width = ((aIdx - 1) * slideSize + aStep * stepSize) + '%';
  }
  
  Dz.postMsg = function(aWin, aMsg) { // [arg0, [arg1...]]
    aMsg = [aMsg];
    for (var i = 2; i < arguments.length; i++)
      aMsg.push(encodeURIComponent(arguments[i]));
    aWin.postMessage(aMsg.join(" "), "*");
  }
  
  function init() {
    Dz.init();
    window.onkeydown = Dz.onkeydown.bind(Dz);
    window.onresize = Dz.onresize.bind(Dz);
    window.onhashchange = Dz.onhashchange.bind(Dz);
    window.onmessage = Dz.onmessage.bind(Dz);
  }

  window.onload = init;
</script>


<script> // Helpers
  if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {

      // closest thing possible to the ECMAScript 5 internal IsCallable
      // function 
      if (typeof this !== "function")
      throw new TypeError(
        "Function.prototype.bind - what is trying to be fBound is not callable"
      );

      var aArgs = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP = function () {},
          fBound = function () {
            return fToBind.apply( this instanceof fNOP ? this : oThis || window,
                   aArgs.concat(Array.prototype.slice.call(arguments)));
          };

      fNOP.prototype = this.prototype;
      fBound.prototype = new fNOP();

      return fBound;
    };
  }

  var $ = (HTMLElement.prototype.$ = function(aQuery) {
    return this.querySelector(aQuery);
  }).bind(document);

  var $$ = (HTMLElement.prototype.$$ = function(aQuery) {
    return this.querySelectorAll(aQuery);
  }).bind(document);

  $$.forEach = function(nodeList, fun) {
    Array.prototype.forEach.call(nodeList, fun);
  }

</script>
<!-- vim: set fdm=marker: }}} -->
